package com.cqhfan.mediaservice.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.cqhfan.core.exceptions.BizException;
import com.cqhfan.core.utils.UserContext;
import com.cqhfan.file.config.MinioProperties;
import com.cqhfan.file.resonse.VideoMsgVO;
import com.cqhfan.file.utils.JcodecVideoUtil;
import com.cqhfan.file.utils.MinIOUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;

/**
 * @author 眭传洪
 * @create 2025-07-30 0:31
 */
@Slf4j
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {

    private final MinioProperties minioProperties;

    /**
     * 图片上传接口，返回图片的地址
     */
    @PostMapping("uploadFace/{prefix}")
    public String uploadFile(@PathVariable("prefix") String prefix, MultipartFile file) {
        // 校验文件
        if (file == null) {
            throw new BizException("文件为空");
        }

        // 生成并拼接文件名
        String fileName = UUID.fastUUID().toString(true);
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BizException("文件错误");
        }
        Long userId = UserContext.getUser();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        fileName = StrUtil.format("{}/{}/{}{}", prefix, userId, fileName, fileExtension);

        // 上传文件
        try {
            MinIOUtils.uploadFile(
                    minioProperties.getBucketName(),
                    fileName,
                    file.getInputStream()
            );
        } catch (Exception e) {
            throw new BizException("文件上传错误");
        }

        // 拼接文件路径
        String url = minioProperties.getFileHost() +
                '/' +
                minioProperties.getBucketName() +
                '/' +
                fileName;

        log.info("文件url: {}", url);

        // 返回地址
        return url;
    }

    @PostMapping("/uploadVideo")
    public VideoMsgVO uploadVideo(MultipartFile file) {
        if (file == null) {
            throw new BizException("文件未传递");
        }

        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BizException("文件上传失败");
        }

        // 拼接文件地址
        Long userId = UserContext.getUser();
        String videoName = "works/" + userId + "/video/" + dealWithFileName(originalFilename);

        // 上传视频文件
        String videoUrl;
        try {
            videoUrl = MinIOUtils.uploadFile(minioProperties.getBucketName(), videoName, file.getInputStream(), true);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }

        // 截取封面 本质上就是视频截帧 一般都是第一帧
        // 1、定义视频封面的名称和路径
        String coverName = UUID.fastUUID().toString(true) + ".jpg";
        String coverPath = JcodecVideoUtil.videoFramesPath + "/videos/" + coverName;

        // 创建封面文件
        File coverFile = new File(coverPath);
        // 父路径不存在的话需要手动创建
        if (coverFile.getParentFile().exists()) {
            boolean success = coverFile.mkdirs();
            if (!success) {
                throw new BizException("封面文件夹创建失败");
            }
        }
        // 上传的视频文件截取第一帧写入到封面文件中
        try {
            JcodecVideoUtil.fetchFrame(file, coverFile);
        } catch (Exception e) {
            throw new BizException("截取帧失败");
        }

        // 上传图片到minio
        String coverUrl;
        try {
            coverUrl = MinIOUtils.uploadFile(minioProperties.getBucketName(), coverName, new FileInputStream(coverFile), true);
        } catch (Exception e) {
            throw new BizException("封面上传失败");
        }

        // 封装返回
        VideoMsgVO result = new VideoMsgVO();
        result.setCover(coverUrl);
        result.setVideoPath(videoUrl);

        return result;
    }

    private String dealWithFileName(String fileName) {
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        return UUID.fastUUID().toString(true) + fileExtension;
    }

}
